#encoding:utf8

import json
import math

from django.shortcuts import render_to_response, get_object_or_404, HttpResponseRedirect
from django.core.urlresolvers import reverse

# Create your views here.
from models import Tasker
from utils.pages import wrap_pages
from utils.tools import get_request_field

from logger import logger


def show(request):
    # template
    template_file = "webserver/show.html"
    # parameters
    size = int(request.GET.get("size", 50))
    page_num = int(request.GET.get("page", 1))
    order = request.GET.get("order", "-created_time")
    title = request.GET.get("title", "")
    # keyword=request.GET.get("keyword", "")

    order_field = order

    start_num, end_num = size*(page_num-1), size*page_num
    objs = []
    item_cnt = 0
    if title:
        objs = Tasker.objects.filter(title__contains="%{}%".format(title)).order_by(order_field)[start_num:end_num]
    else:
        objs = Tasker.objects.order_by(order_field)[start_num:end_num]
    #
    item_cnt = Tasker.objects.count()
    max_page = int(math.ceil(item_cnt * 1.0 / size))
    next_page = page_num + 1
    if next_page > max_page: next_page = None
    before_page = page_num - 1
    if before_page < 1: before_page = None

    path = request.path
    item_cnt = int(item_cnt)
    # max_page = int(max_page)
    # page_url = "%s?source=%s&order=%s&size=%s&page_num=%s"
    # before_page_url = page_url%(path, source, order, size, before_page) if before_page else None
    # next_page_url = page_url%(path, source, order, size, next_page) if next_page else None

    obj_infos = []
    for obj in objs:
        obj_info = obj.get_info()
        obj_info['pos_url'] = reverse("webserver:show_item", args=(obj.id, ))
        obj_infos.append(obj_info)

    page_url = "{0}?title={1}&order={2}&page=%s&size={3}".format(path, title, order, size)
    page_info = wrap_pages(page_url, cnt=item_cnt, size=size, cur=page_num, span=10)

    # info=dict(start_num=start_num, end_num=max(end_num, item_cnt), next_page=next_page,
    #           next_page_url=next_page_url, before_page=before_page, before_page_url=before_page_url,
    #           size=size, max_page=max_page, item_cnt=item_cnt)
    data = dict(title=title, order=order, page_num=page_num, size=size,
                items=obj_infos, page_info=page_info)

    return render_to_response(template_file, data)


def show_item(request, id):
    template_file = "webserver/show_item.html"
    # id = get_request_field(request, "id", must=True, blank=False)
    # obj = Tasker.objects.get(id=id)
    obj = get_object_or_404(Tasker, id=id)

    return render_to_response(template_file, {"obj": obj.get_info()})


def insert(request):
    template_file = "webserver/insert.html"
    method = request.method
    d = {}
    errors = []
    if method == 'POST':
        title = get_request_field(request, "title", must=False, default="")
        func = get_request_field(request, "func", must=True, default="")
        args = get_request_field(request, "args", must=True, default="")
        priority = get_request_field(request, "priority", must=False, default=5)

        cron_type = get_request_field(request, "cron_type", must=True, default="cron")
        cron_params = get_request_field(request, "cron_params", must=False, default="")

        d = dict(
            title=title, func=func, args=args, priority=priority,
            cron_type=cron_type, cron_params=cron_params,
        )

        # 检查是否合格
        check_func_args(func, args, errors)

        # 检查定时任务是否合格
        check_cron_params(cron_type, cron_params, errors)

        if not errors:
            obj = Tasker.objects.create(**d)
            obj.save()
            obj_page = reverse("webserver:show_item", args=(obj.id, ))
            logger.info("[INSERT NEW TASK], task id: [{0}], details: [{1}]".format(obj.id, json.dumps(obj.get_info())))
            return HttpResponseRedirect(obj_page)

    return render_to_response(template_file, {"obj": d, 'errors': errors})


def check_func_args(func_name, args, errors):
    if not func_name:
        errors.append("func_name: should not be empty")


def check_cron_params(cron_type, cron_params, errors):
    if not cron_type or cron_type not in ['cron', 'interval', 'date']:
        errors.append("cron_type: should only be cron|interval|date")
    if not cron_params:
        errors.append("cron_params: should set")


def update(request, id):
    template_file = "webserver/update.html"
    # id = get_request_field(request, "id", must=False, default="")
    obj = get_object_or_404(Tasker, id=id)
    d = obj.get_info()

    errors = []
    method = request.method
    if method == 'POST':
        title = get_request_field(request, "title", must=False, default="")
        func = get_request_field(request, "func", must=True, default="")
        args = get_request_field(request, "args", must=True, default="")
        priority = get_request_field(request, "priority", must=False, default=5)

        cron_type = get_request_field(request, "cron_type", must=True, default="cron")
        cron_params = get_request_field(request, "cron_params", must=False, default="")

        d = dict(
            title=title, func=func, args=args, priority=priority,
            cron_type=cron_type, cron_params=cron_params,
        )

        # 检查是否合格
        check_func_args(func, args, errors)

        # 检查定时任务是否合格
        check_cron_params(cron_type, cron_params, errors)

        if not errors:
            update_fields = []
            if title is not None:
                obj.title = title
                update_fields.append('title')
            if func is not None:
                obj.func = func
                update_fields.append('func')
            if args is not None:
                obj.args = args
                update_fields.append('args')
            if priority is not None:
                obj.priority = priority
                update_fields.append('priority')
            if cron_type is not None:
                obj.cron_type = cron_type
                update_fields.append('cron_type')
            if cron_params is not None:
                obj.cron_params = cron_params
                update_fields.append('cron_params')

            if update_fields:
                # 说明有更新
                obj.status = 2
                update_fields.append("status")
                obj.save(update_fields=update_fields)

            obj_page = reverse("webserver:show_item", args=(obj.id, ))
            logger.info("[UPDATE TASK], task id: [{0}], details: [{1}]".format(obj.id, json.dumps(obj.get_info())))
            return HttpResponseRedirect(obj_page)

    return render_to_response(template_file, {"obj": d, 'errors': []})


def delete_item(request, id):
    # id = get_request_field(request, "id", must=True, blank=False)
    # obj = Tasker.objects.get(id=id)
    obj = get_object_or_404(Tasker, id=id)
    obj.delete()
    logger.info("[DELETE TASK], id: [{0}]".format(id))
    return HttpResponseRedirect(reverse("webserver:show"))
